package com.fishery.processing.async;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fishery.entity.GlobalException;
import com.fishery.entity.Result;
import com.fishery.entity.StatusCode;
import com.fishery.processing.client.BaseClient;
import com.fishery.processing.entity.Input;
import com.fishery.processing.entity.root.FactoryRootVo;
import com.fishery.processing.entity.root.JobRootVo;
import com.fishery.processing.entity.vo.InputVo;
import com.fishery.processing.entity.vo.QualificationVo;
import com.fishery.processing.entity.vo.RootMessageVo;
import com.fishery.processing.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * @author run
 * @since 2021/3/13 11:14
 */
@Component
public class BatchAsync {

    @Autowired
    private BaseClient baseClient;

    @Autowired
    private FactoryMapper factoryMapper;

    @Autowired
    private QualificationMapper qualificationMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private InputMapper inputMapper;

    @Autowired
    private CraftMapper craftMapper;

    @Autowired
    private JobMapper jobMapper;


    @Async("asyncTaskExecutor")
    public void setFactoryMessage(RootMessageVo message, String factoryId, CountDownLatch count){
        FactoryRootVo factoryRootVo = factoryMapper.getFactoryRootVoById(factoryId);
        Result baseMessage = baseClient.getBaseMessage(factoryRootVo.getBaseId());
        if (baseMessage.getStatusCode() != StatusCode.OK.getCode()){
            throw new GlobalException(StatusCode.ERROR, "获取基地信息失败");
        }
        JSONObject baseObject = JSONObject.parseObject(JSON.toJSONString(baseMessage.getData()));
        String baseName = baseObject.get("name").toString();

        message.setFactoryName(factoryRootVo.getFactoryName());
        message.setBaseName(baseName);
    }

    @Async("asyncTaskExecutor")
    public void setProductMessage(RootMessageVo message, String productId, CountDownLatch count){
        String productName = productMapper.getProductNameById(productId);
        message.setProductName(productName);
        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public void setQualificationMessage(RootMessageVo message, String productId, CountDownLatch count){
        QualificationVo qualification = qualificationMapper.getQualificationOfProduct(productId);
        message.setQualification(qualification);
        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public void setInputMessage(RootMessageVo message, String productId, CountDownLatch count){
        List<String> craftId = craftMapper.getCraftIdOfProduct(productId);
        Map<String,List<InputVo>> inputs = new HashMap<>(craftId.size(), 1);
        craftId.forEach((id)->inputs.put(id, null));
        CountDownLatch inputCount = new CountDownLatch(craftId.size());
        craftId.forEach((id)->setInputOfCraft(inputs, id, inputCount));

        try {
            inputCount.await();
        } catch (InterruptedException e) {
            throw new GlobalException(StatusCode.ERROR,"投入品信息获取失败");
        }

        List<InputVo> inputVos = new ArrayList<>();
        inputs.forEach((key, value)->inputVos.addAll(value));
        message.setInputVoList(inputVos);

        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public void setInputOfCraft(Map<String, List<InputVo>> map, String craftId, CountDownLatch count){
        List<InputVo> inputs = inputMapper.getInputsOfCraft(craftId);
        map.put(craftId, inputs);
        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public void setJobMessage(RootMessageVo message, String jobId, CountDownLatch count){
        JobRootVo jobRootVo = jobMapper.getJobRootMessage(jobId);
        message.setStartTime(jobRootVo.getStartTime());
        message.setEndTime(jobRootVo.getEndTime());
        message.setOperatorName(jobRootVo.getOperatorName());

        CountDownLatch productCount = new CountDownLatch(3);

        String productId = jobRootVo.getProductId();
        setProductMessage(message, productId, productCount);
        setInputMessage(message, productId, productCount);
        setQualificationMessage(message, productId, productCount);

        try {
            productCount.await();
        } catch (InterruptedException e) {
            throw new GlobalException(StatusCode.ERROR,"产品信息获取失败");
        }

        count.countDown();

    }


}
